/*
 * MIT License
 *
 * Copyright (c) 2023 北京凯特伟业科技有限公司
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
package com.je.message.service.dingtalk.impl;

import com.dingtalk.api.DefaultDingTalkClient;
import com.dingtalk.api.DingTalkClient;
import com.dingtalk.api.request.OapiGettokenRequest;
import com.dingtalk.api.request.OapiMessageCorpconversationAsyncsendV2Request;
import com.dingtalk.api.response.OapiGettokenResponse;
import com.dingtalk.api.response.OapiMessageCorpconversationAsyncsendV2Response;
import com.je.common.base.DynaBean;
import com.je.common.base.mapper.query.NativeQuery;
import com.je.common.base.service.MetaRbacService;
import com.je.message.service.dingtalk.DingTalkService;
import com.je.message.vo.dingTalk.*;
import com.taobao.api.ApiException;
import com.taobao.api.TaobaoObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@Service
public class DingTalkServiceImpl implements DingTalkService {

    @Autowired
    private MetaRbacService metaRbacService;

    private static final Logger logger = LoggerFactory.getLogger(DingTalkServiceImpl.class);

    private static final String MESSAGE_SERVER_URL = "https://oapi.dingtalk.com/topapi/message/corpconversation/asyncsend_v2";

    private static final String ACCESS_TOKEN_URL = "https://oapi.dingtalk.com/gettoken";

    @Override
    public void send(DingTalkMsg msgVo, AbstractDingTalkWorkNotice abstractDingTalkWorkNotice) {
        String id = msgVo.getJeCloudDingTalkId();
        DynaBean dynaBean = metaRbacService.selectOneByPk("JE_RBAC_DINGTALK_CONFIG", id);
        String appKey = dynaBean.getStr("CONFIG_APPKEY");
        String appSecret = dynaBean.getStr("CONFIG_APPSECRET");
        String agentId = dynaBean.getStr("CONFIG_APPID");
        TaobaoObject obj = null;
        if (abstractDingTalkWorkNotice instanceof DingTalkTextWorkNotice) {
            OapiMessageCorpconversationAsyncsendV2Request.Text text = new OapiMessageCorpconversationAsyncsendV2Request.Text();
            DingTalkTextWorkNotice dingTalkTextWorkNotice = (DingTalkTextWorkNotice) abstractDingTalkWorkNotice;
            text.setContent(dingTalkTextWorkNotice.getContent());
            obj = text;
        } else if (abstractDingTalkWorkNotice instanceof DingTalkActionCardWorkNotice) {
            OapiMessageCorpconversationAsyncsendV2Request.ActionCard actionCard = new OapiMessageCorpconversationAsyncsendV2Request.ActionCard();
            DingTalkActionCardWorkNotice dingTalkActionCardWorkNotice = (DingTalkActionCardWorkNotice) abstractDingTalkWorkNotice;
            actionCard.setTitle(dingTalkActionCardWorkNotice.getTitle());
            actionCard.setMarkdown(dingTalkActionCardWorkNotice.getContent());
            if (dingTalkActionCardWorkNotice.getBtnInfoList().size() > 1) {
                List<OapiMessageCorpconversationAsyncsendV2Request.BtnJsonList> btnJsonList = new ArrayList<>();
                for (DingTalkActionCardWorkNotice.BtnInfo btnInfo : dingTalkActionCardWorkNotice.getBtnInfoList()) {
                    OapiMessageCorpconversationAsyncsendV2Request.BtnJsonList btnJsonList1 = new OapiMessageCorpconversationAsyncsendV2Request.BtnJsonList();
                    btnJsonList1.setTitle(btnInfo.getTitle());
                    btnJsonList1.setActionUrl(btnInfo.getUrl());
                    btnJsonList.add(btnJsonList1);
                }
                actionCard.setBtnJsonList(btnJsonList);
            } else {
                DingTalkActionCardWorkNotice.BtnInfo btnInfo = dingTalkActionCardWorkNotice.getBtnInfoList().get(0);
                actionCard.setSingleTitle(btnInfo.getTitle());
                actionCard.setSingleUrl(btnInfo.getUrl());
            }
            obj = actionCard;
        } else if (abstractDingTalkWorkNotice instanceof DingTalkMarkDownWorkNotice) {
            OapiMessageCorpconversationAsyncsendV2Request.Markdown markdown = new OapiMessageCorpconversationAsyncsendV2Request.Markdown();
            DingTalkMarkDownWorkNotice dingTalkMarkDownWorkNotice = (DingTalkMarkDownWorkNotice) abstractDingTalkWorkNotice;
            markdown.setTitle(dingTalkMarkDownWorkNotice.getTitle());
            markdown.setText("【" + dingTalkMarkDownWorkNotice.getTitle() + "】<br/>" + dingTalkMarkDownWorkNotice.getContent());
            obj = markdown;
        }
        try {
            sendCardMsg(obj, getDingTalkIds(msgVo.getToUserIds(), msgVo.getJeCloudDingTalkId()), appKey, appSecret, agentId);
        } catch (ApiException e) {
            e.printStackTrace();
        }
    }

    private String getDingTalkIds(List<String> jeCloudUserIds, String foreignKey) {
        List<DynaBean> list = metaRbacService.selectByNativeQuery(NativeQuery.build().tableCode("JE_RBAC_ACCOUNT")
                .in("USER_ASSOCIATION_ID", jeCloudUserIds));

        List<String> accountIds = new ArrayList<>();
        for (DynaBean dynaBean : list) {
            logger.info("JECLOUD用户id=" + dynaBean.getStr("JE_RBAC_ACCOUNT_ID"));
            if (accountIds.contains(dynaBean.getStr("JE_RBAC_ACCOUNT_ID"))) {
                continue;
            }
            logger.info("JECLOUD用户2id=" + dynaBean.getStr("JE_RBAC_ACCOUNT_ID"));
            accountIds.add(dynaBean.getStr("JE_RBAC_ACCOUNT_ID"));
        }

        List<DynaBean> cpUsers = metaRbacService.selectByNativeQuery(NativeQuery.build().tableCode("JE_RBAC_CPUSER")
                .in("CPUSER_BDYH_ID", accountIds).eq("CPUSER_TYPE", "DINGTALK")
                .eq("CPUSER_FOREIGNKEY", foreignKey));
        logger.info("foreignKey=" + foreignKey);
        List<String> cpUserIds = new ArrayList<>();
        for (DynaBean dynaBean : cpUsers) {
            logger.info("推送钉钉用户id=" + dynaBean.getStr("CPUSER_ZH"));
            if (cpUserIds.contains(dynaBean.getStr("CPUSER_ZH"))) {
                continue;
            }
            cpUserIds.add(dynaBean.getStr("CPUSER_ZH"));
        }
        return String.join(",", cpUserIds);
    }

    public OapiMessageCorpconversationAsyncsendV2Response sendCardMsg(TaobaoObject message, String userIds,
                                                                      String appKey, String appSecret, String agentId) throws ApiException {
        DingTalkClient client = new DefaultDingTalkClient(MESSAGE_SERVER_URL);
        OapiMessageCorpconversationAsyncsendV2Request req = new OapiMessageCorpconversationAsyncsendV2Request();
        req.setAgentId(Long.parseLong(agentId));
        req.setUseridList(userIds);
        //构建消息对象
        OapiMessageCorpconversationAsyncsendV2Request.Msg msg = new OapiMessageCorpconversationAsyncsendV2Request.Msg();
        if (message instanceof OapiMessageCorpconversationAsyncsendV2Request.ActionCard) {
            msg.setActionCard((OapiMessageCorpconversationAsyncsendV2Request.ActionCard) message);
            msg.setMsgtype("action_card");
            req.setMsg(msg);
        } else if (message instanceof OapiMessageCorpconversationAsyncsendV2Request.Markdown) {
            msg.setMarkdown((OapiMessageCorpconversationAsyncsendV2Request.Markdown) message);
            msg.setMsgtype("markdown");
            req.setMsg(msg);
        } else if (message instanceof OapiMessageCorpconversationAsyncsendV2Request.Text) {
            msg.setText((OapiMessageCorpconversationAsyncsendV2Request.Text) message);
            msg.setMsgtype("text");
            req.setMsg(msg);
        }
        OapiMessageCorpconversationAsyncsendV2Response rsp = client.execute(req, buildAccessToken(appKey, appSecret));
        return rsp;
    }


    private String buildAccessToken(String appKey, String appSecret) throws ApiException {
        //获取token
        DefaultDingTalkClient client = new DefaultDingTalkClient(ACCESS_TOKEN_URL);
        OapiGettokenRequest request = new OapiGettokenRequest();
        request.setAppkey(appKey);
        request.setAppsecret(appSecret);
        request.setHttpMethod("GET");
        OapiGettokenResponse response = client.execute(request);
        return response.getAccessToken();
    }

}
